- Understand how to improve performance with your Java code using Java 8 language features.
- Learn hands on techniques to discover and implement common Java 8 refactorings.
- Understand when you should and should not apply key refactorings in Java 8.
Abstract
While we’re drawing ever closer to Java 9, and even hearing about features in Java 10, many of us are still working with an older version. Even if your project has technically adopted Java 8, and even if you’re using it when coding new features, it’s likely that the majority of your code base is still not making the most of what’s available in Java 8 - features like Lambda Expressions, the Streams API, and new Date/Time. And this is a shame, since Java 8 provides not only nicer syntax for developers, but (usually) better application performance.
In this presentation, Trisha will:
- Highlight the performance benefits of using Java 8 - after all, you’ll probably have to persuade "The Management" that tampering with existing code is worthwhile
- Demonstrate how to identify areas of code that can be updated to use Java 8 features, and how to pick which changes will give you the most benefit
- Demonstrate how to automatically refactor your code to make use of features like lambdas and streams
- Cover some of the pros and cons of using the new features - including suggestions of when refactoring may NOT be the best idea.
The talk
This is the most complete version of the talk, containing as many different refactorings as I could squeeze in, and updated performance analysis.
Other versions include:
- JetBrains Webinar, with all the latest IntelliJ IDEA support for Java 8 refactoring.
- QCon New York, with a nice summary of the points covered in the talk.
- DevoxxUK
You can purchase a more in-depth tutorial on informIT, and is also available via Safari Books Online.
The IntelliJ-specific features of some of the refactoring shown are covered in my Migrating to Java 8 tutorial.
Background
- Article: Why Java 8
- Article: Five Java 8 Features You Won't Be Able to Live Without
- Video and Research: Building a Java 8 Application
Code
The project we're refactoring is Morphia. You can see the "after" of the chosen refactorings on the r2j8 branch.
The performance tests that were written and run specifically for this talk are in the j8-morphia-perf-tests repository
Performance
Lambda Expressions
- Video: Lambda Performance and [talk slides](http://www.oracle .com/technetwork/java/jvmls2013kuksen-2014088.pdf)
- Article: Java 8 Lambdas - A Peek Under the Hood
- Video: Lambdas in Java: A Peek under the Hood - Brian Goetz
Streams
- Video: Let’s Get to the Rapids: Java 8 Stream Performance
- Article: Java performance tutorial: How fast are the Java 8 streams? - Angelika Langer Notable Quotes:
Again, the for-loop is faster that the sequential stream operation, but the difference on an ArrayList is not nearly as significant as
it was on an array.
You will find that there is no measurable difference any more between for-loop and sequential stream if the functionality is heavily cpu
bound.
The point to take home is that sequential streams are no faster than loops. If you use sequential streams then you don’t do it for
performance reasons; you do it because you like the functional programming style.
The reality check via our benchmark yields a ratio (sequential / parallel) of only 1.6 instead of 2.0, which illustrates the amount of
overhead that is involved in going parallel and how (well or poorly) it is overcompensated (on this particular platform).
With this in mind it is fair to say that the performance model of streams is not a trivial one
...you need to benchmark a lot in order to find out for a given context whether going parallel is worth doing or not.
The realisation is: Yes, parallel stream operations are easy to use and often they run faster than sequential operations, but don’t
expect miracles. Also, don’t guess; instead, benchmark a lot.
- Article: Benchmark: How Misusing Streams Can Make Your Code 5 Times Slower - interesting comparison of different iteration styles. Also shows that things like boxing might add more cost than streams (but that you don't realise you're boxing)
- Article: Stream Performance - some interesting benchmarks based on Angelika Langer's article
- Article: Follow up on Stream Performance
Date and Time
Article: JSR 310 – Java 8 Date/Time library performance (as well as Joda Time 2.3 and j.u.Calendar)
Benchmarking
I used a bunch of techniques to produce the benchmarks on the talk. I'd like to summarise them more thoroughly when I get a chance, but for now here's my background reading:
Article: Avoiding Benchmarking Pitfalls on the JVM
Tool: JMH
Tool: IntelliJ JMH Plugin
Article: Introduction to JMH
"Best Practice"
I dislike the term "Best Practice" as it implies a "one size fits all" approach, and I believe that our job is to make difficult decisions based on various pros and cons and differing situations. However, here I will collect resources that may help us make some of those decisions
Article: Refactoring with Loops and Collection Pipelines -
Martin Fowler
Slides: Workflows of Refactoring - Martin Fowler
Book: Refactoring: Improving the Design of Existing Code - Martin Fowler
Article: Using Optional in Java SE 8 - Stephen Colebourne
Article: Java 8 Best Practices Cheat Sheet - ZeroTurnaround